/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2009，所有权利保留。
 * 
 * 项目名：	rumba-widget2
 * 文件名：	RTip.java
 * 模块说明：	
 * 修改历史：
 * Feb 14, 2009 - lxm - 创建。
 */
package com.hd123.rumba.gwt.widget2.client.tip;

import java.util.ArrayList;
import java.util.List;

import com.hd123.rumba.gwt.widget2.client.form.RValidator.ValidLevel;
import com.hd123.rumba.gwt.widget2.client.form.RValidator.ValidResult;

/**
 * 提示信息数据对象。提供对提示信息存取的功能，其中的数据可以被RTipButton理解，并以恰当的形式显示出来。
 * 
 * @author lxm
 * 
 */
public class RTip {

  private RTipButton button;
  /** 包含的强制提示信息列表。 List of RTipInfo */
  private ArrayList forcedTips = new ArrayList();
  /** 包含的提示信息列表。 List of RTipInfo */
  private ArrayList tips = new ArrayList();
  /** 包含的侦听器对象列表。 List of RTipListener */
  private ArrayList tipListeners = new ArrayList();

  /**
   * 清除所有已经被加入的提示信息。
   */
  public void clear() {
    clear(false);
  }

  /**
   * 清除所有已经被加入的提示信息。
   * 
   * @param includeForced
   *          指定是否一起清除强制提示。
   */
  public void clear(boolean includeForced) {
    tips.clear();
    if (includeForced)
      forcedTips.clear();
    if (button != null)
      button.refresh();
    fireOnChanged();
  }

  /**
   * 添加一个提示信息。
   * 
   * @param tipInfo
   *          指定一个被加入的提示信息。
   */
  public void add(RTipInfo tipInfo) {
    add(tipInfo, false);
  }

  /**
   * 添加一个提示信息。
   * 
   * @param tipInfo
   *          指定一个被加入的提示信息。
   * @param forced
   *          指定所添加的是否是强制的。
   */
  public void add(RTipInfo tipInfo, boolean forced) {
    if (tipInfo == null)
      return;
    if (forced)
      forcedTips.add(tipInfo);
    else
      tips.add(tipInfo);
    if (button != null)
      button.refresh();
    fireOnChanged();
  }

  /**
   * 添加一个提示信息
   * 
   * @param validResult
   */
  public void add(ValidResult validResult) {
    if (validResult.getLevel().equals(ValidLevel.info)) {
      if (validResult.getMessage() != null && !validResult.getMessage().equals(""))
        addInfo(validResult.getMessage());
    } else if (validResult.getLevel().equals(ValidLevel.warning))
      addWarning(validResult.getMessage());
    else if (validResult.getLevel().equals(ValidLevel.error))
      addError(validResult.getMessage());
  }

  /**
   * 添加一个错误级别的提示信息。
   * 
   * @param message
   *          指定提示信息文本。
   */
  public void addError(String message) {
    add(RTipInfo.error(message), false);
  }

  /**
   * 添加一个错误级别的提示信息。
   * 
   * @param message
   *          指定提示信息文本。
   * @param forced
   *          指定所添加的是否是强制的。
   */
  public void addError(String message, boolean forced) {
    add(RTipInfo.error(message), forced);
  }

  /**
   * 添加一个警告级别的提示信息。
   * 
   * @param message
   *          指定提示信息文本。
   */
  public void addWarning(String message) {
    add(RTipInfo.warning(message), false);
  }

  /**
   * 添加一个警告级别的提示信息。
   * 
   * @param message
   *          指定提示信息文本。
   * @param forced
   *          指定所添加的是否是强制的。
   */
  public void addWarning(String message, boolean forced) {
    add(RTipInfo.warning(message), forced);
  }

  /**
   * 添加一个信息级别的提示信息。
   * 
   * @param message
   *          指定提示信息文本。
   */
  public void addInfo(String message) {
    add(RTipInfo.info(message), false);
  }

  /**
   * 添加一个信息级别的提示信息。
   * 
   * @param message
   *          指定提示信息文本。
   * @param forced
   *          指定所添加的是否是强制的。
   */
  public void addInfo(String message, boolean forced) {
    add(RTipInfo.info(message), forced);
  }

  /**
   * 取得当前所拥有的提示信息的数量。
   * 
   * @return
   */
  public int getCount() {
    return getCount(false);
  }

  /**
   * 取得当前所拥有的提示信息的数量。
   * 
   * @param includeForced
   *          指定是否包括所有强制的。
   * @return
   */
  public int getCount(boolean includeForced) {
    int cnt = tips.size();
    if (includeForced)
      cnt += forcedTips.size();
    return cnt;
  }

  /**
   * 取得所有已经被加入的提示信息。
   * 
   * @return 返回提示信息列表。
   */
  public List all() {
    return all(false);
  }

  /**
   * 取得所有已经被加入的提示信息。
   * 
   * @param includeForced
   *          指定是否包括所有强制的。
   * @return 返回提示信息列表。
   */
  public List all(boolean includeForced) {
    ArrayList list = new ArrayList();
    if (includeForced)
      list.addAll(forcedTips);
    list.addAll(tips);
    return list;
  }

  /**
   * 取得当前是否验证通过。
   * 
   * @return
   */
  public boolean isValid() {
    RTipInfo tip = getDisplayed();
    return tip == null ? true : tip.getLevel().isValid();
  }

  /**
   * 添加提示侦听器。
   * 
   * @param listener
   *          指定被添加的侦听器对象。not null。
   */
  public void addTipListener(RTipListener listener) {
    if (listener == null)
      return;
    tipListeners.add(listener);
  }

  /**
   * 删除指定的侦听器对象。
   * 
   * @param listener
   *          指定被删除的侦听器对象。not null。
   */
  public void removeTipListener(RTipListener listener) {
    if (listener == null)
      return;
    tipListeners.remove(listener);
  }

  /**
   * 取得当前所对应的提示显示控件对象。
   * 
   * @return
   */
  public RTipButton getButton() {
    return button;
  }

  /**
   * 设置对应的提示信息显示控件对象。
   * 
   * @param button
   */
  void setButton(RTipButton button) {
    this.button = button;
  }

  /**
   * 取得当前显示的提示信息。
   * 
   * @return
   */
  public RTipInfo getDisplayed() {
    RTipInfo displayed = null;

    for (int i = 0, n = tips.size(); i < n; i++) {
      RTipInfo tip = (RTipInfo) tips.get(i);
      if (displayed == null)
        displayed = tip;
      else if (displayed.getLevel().compareTo(tip.getLevel()) < 0)
        displayed = tip;
    }

    for (int i = 0, n = forcedTips.size(); i < n; i++) {
      RTipInfo tip = (RTipInfo) forcedTips.get(i);
      if (displayed == null)
        displayed = tip;
      else if (displayed.getLevel().compareTo(tip.getLevel()) < 0)
        displayed = tip;
    }

    return displayed;
  }

  private void fireOnChanged() {
    for (int i = 0, n = tipListeners.size(); i < n; i++) {
      RTipListener listener = (RTipListener) tipListeners.get(i);
      if (listener != null)
        listener.onChanged(this);
    }
  }
}
